#!/usr/bin/python2.4
#
# Copyright 2009-2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========================================================================

Import('env')

import binascii
import md5
from enterprise.installer import build_enterprise_installer


def BuildMSI(version, namespace, exe_name, wxs_template, msi_base_name,
             is_enterprise=False, prefix=''):
  if is_enterprise:
    msi_base_name = 'enterprise_' + msi_base_name
  msi_base_name = prefix + msi_base_name

  # Have to use 'copy' here because we are renaming the file, and it is being
  # renamed to match the final msi name to avoid collisions in the wixobj files.
  copy_target = env.Command(
      target=msi_base_name + '.wxs',
      source=wxs_template,
      action='@copy /y $SOURCE $TARGET',
  )

  PRODUCT_GUID = build_enterprise_installer.GenerateNameBasedGUID(
      namespace,
      'Product ' + version
  )
  COMPONENT_GUID = build_enterprise_installer.GenerateNameBasedGUID(
      namespace,
      'Component ' + version
  )
  COMPONENT_GUID_REGISTRY = build_enterprise_installer.GenerateNameBasedGUID(
      namespace,
      'Component Registry ' + version
  )
  COMPONENT_GUID_NOTIFY_SUCCESS = (
      build_enterprise_installer.GenerateNameBasedGUID(
          namespace,
          'Component Notify Success ' + version
      ))
  COMPONENT_GUID_REGISTER_LAUNCH = (
      build_enterprise_installer.GenerateNameBasedGUID(
          namespace,
          'Component Register Launch Command ' + version
      ))
  COMPONENT_GUID_NOTIFY_FAILED = (
      build_enterprise_installer.GenerateNameBasedGUID(
          namespace,
          'Component Notify Failed ' + version
      ))
  COMPONENT_GUID_PROPERTY_BAR = (
      build_enterprise_installer.GenerateNameBasedGUID(
          namespace,
          'Component Property Bar ' + version
      ))

  wix_env = env.Clone()
  wix_env.Append(
      WIXLIGHTFLAGS = [
          # Add a supress for:
          # warning LGHT1076 : ICE91: The file will be installed to the per user
          # directory that doesn't vary based on ALLUSERS value. This file won't
          # be copied to each user's profile even if a per machine installation
          # is desired.
          # This warning is generated by light when we produce a user only
          # installer, and can be ignored as this is a user only installer.
          '-sw1076'
          ],
      WIXCANDLEFLAGS = [
          '-dFooExePath=' + wix_env.File(exe_name).abspath,
          '-dFooVersion=' + version,
          '-dFooProductGuid=' + PRODUCT_GUID,
          '-dFooComponentGuid=' + COMPONENT_GUID,
          '-dFooComponentGuidRegistry=' + COMPONENT_GUID_REGISTRY,
          '-dFooComponentGuidNotifySuccess=' + COMPONENT_GUID_NOTIFY_SUCCESS,
          '-dFooComponentRegisterLaunchCommand=' +
              COMPONENT_GUID_REGISTER_LAUNCH,
          '-dFooComponentGuidNotifyFailed=' + COMPONENT_GUID_NOTIFY_FAILED,
          '-dFooComponentGuidPropertyBar=' + COMPONENT_GUID_PROPERTY_BAR,
          ],
  )

  wix_inputs = copy_target
  # Force a rebuild when the exe file changes.
  additional_dependencies = [exe_name]

  if is_enterprise:
    output_dir = '$TARGET_ROOT/Test_Installers'
    wix_env['WIXCANDLEFLAGS'] += ['-dIsEnterprise=1']

    # The metainstaller change does not get passed through even though the
    # .wixobj file is rebuilt because the hash of the .wixobj does not change.
    metainstaller_path = '$STAGING_DIR/%sGoogleUpdateSetup.exe' % (prefix)
    google_update_wixobj = build_enterprise_installer.BuildGoogleUpdateFragment(
            env,
            metainstaller_path,
            'Test Foo',
            version,
            '{D6B08267-B440-4c85-9F79-E195E80D9937}',
            '&ap=enterprise',
            msi_base_name,
            ('$MAIN_DIR/enterprise/installer/'
                'google_update_installer_fragment.wxs.xml')
    )

    wix_inputs += [google_update_wixobj]
    additional_dependencies += [metainstaller_path]
  else:
    output_dir = '$TESTS_DIR'
    wix_env['WIXCANDLEFLAGS'] += ['-dIsEnterprise=0']

  unsigned_msi = wix_env.WiX('unsigned_%s.msi' % msi_base_name, wix_inputs)

  wix_env.Depends(unsigned_msi, additional_dependencies)

  signed_output = env.SignedBinary(
      target=msi_base_name + '.msi',
      source=unsigned_msi,
  )

  env.Replicate(output_dir, signed_output)

_GUID_NAMESPACE = binascii.a2b_hex('BE19B3E4502845af8B3E67A99FCDCFB1')
_USER_GUID_NAMESPACE = binascii.a2b_hex('2B599C061F7C4eed9D686616EEBDDFDB')

# test_foo.wxs.xml is so named because SCons tries to apply WiX building
# rules to any input file with the .wxs suffix even in a custom command.
_WXS_TEMPLATE_NAME = 'test_foo.wxs.xml'
_USER_WXS_TEMPLATE_NAME = 'user_app.wxs.xml'

for (major, minor, build, patch) in [(1,0,101,0), (1,0,102,0)]:
  version = '%d.%d.%d.%d' % (major, minor, build, patch)
  msi_base_name = 'test_foo_v' + version

  ver_env = env.Clone()
  ver_env.Append(
      LIBS = [
          ('libcmt.lib', 'libcmtd.lib')[env.Bit('debug')],
          ('libcpmt.lib', 'libcpmtd.lib')[env.Bit('debug')],
          'version.lib',
          ],
      RCFLAGS = [
          '-DVERSION_STRING=%s' % version,
          '-DMAJOR=%s' % major,
          '-DMINOR=%s' % minor,
          '-DBUILD=%s' % build,
          '-DPATCH=%s' % patch
          ],
  )

  ver_env['OBJPREFIX'] = '%s%s/' % (ver_env['OBJPREFIX'], version)

  base_name = 'test_foo_v%s' % version.replace('.', '_')
  signed_target_name = base_name + '.exe'
  target_name = base_name + '_unsigned'

  unsigned_exe = ver_env.ComponentTestProgram(
      prog_name=target_name,
      source=[
          'test_foo.cc',
          ver_env.RES('test_foo_v%s.res' % version, 'test_foo.rc'),
          ],
      COMPONENT_TEST_RUNNABLE=False
  )

  signed_output = ver_env.SignedBinary(
      target=signed_target_name,
      source=unsigned_exe,
  )

  ver_env.Replicate('$TESTS_DIR', signed_output)

  signed_exe = signed_output[0]

  BuildMSI(version, _GUID_NAMESPACE, signed_exe, _WXS_TEMPLATE_NAME,
           msi_base_name)

  # Build the enterprise installer for each version of Omaha.
  for omaha_version_info in ver_env['omaha_versions_info']:
    prefix = omaha_version_info.filename_prefix

    BuildMSI(version, _GUID_NAMESPACE, signed_exe, _WXS_TEMPLATE_NAME,
             msi_base_name, is_enterprise=True, prefix=prefix)

  BuildMSI(version, _USER_GUID_NAMESPACE, signed_exe, _USER_WXS_TEMPLATE_NAME,
           'user_app_v' + version)

bar_env = env.Clone()
bar_env.Append(
    LIBS = [
        ('libcmt.lib', 'libcmtd.lib')[env.Bit('debug')],
        ('libcpmt.lib', 'libcpmtd.lib')[env.Bit('debug')],
        ],
)
bar_env.ComponentTestProgram(prog_name='test_bar',
                             source='test_bar.cc',
                             COMPONENT_TEST_RUNNABLE=False)


""" This is commented out because it step_test is currently unused,
    and may be removed. Remove this if/when step_test is removed.

omaha_system_env = env.Clone()
omaha_system_env.Append(
    CPPDEFINES = [
        'UNICODE',
        '_UNICODE'
        ],
    LIBS = [
        '$LIB_PATH/common.lib',
        ('atls.lib', 'atlsd.lib')[env.Bit('debug')],
        ('libcmt.lib', 'libcmtd.lib')[env.Bit('debug')],
        ('libcpmt.lib', 'libcpmtd.lib')[env.Bit('debug')],
        ],
)


omaha_system_env.FilterOut(LINKFLAGS = ['/SUBSYSTEM:WINDOWS'])
omaha_system_env['LINKFLAGS'] += ['/SUBSYSTEM:CONSOLE']

omaha_system_env.ComponentTestProgram([
    'omaha_system_test.cc',
    'step_test.cc',
    ],
    COMPONENT_TEST_RUNNABLE=False
)
"""

